iT邦幫忙

2025 iThome 鐵人賽

DAY 12
0
Software Development

從零開始學 Python系列 第 12

Day 12 – 變數作用域(Variable Scope)與 global/local

  • 分享至 

  • xImage
  •  

今天的學習重點

  • 作用域(Scope):變數可以被存取的範圍
  • Local(區域變數):在函式內宣告的變數,只能在該函式內使用
  • Global(全域變數):在所有函式外宣告的變數,可以在整個程式中使用
  • global 關鍵字:在函式內修改全域變數的方式

一、區域變數與全域變數

x = 10  # 全域變數

def my_func():
    x = 5  # 區域變數
    print("函式內 x =", x)

my_func()
print("函式外 x =", x)

輸出:

函式內 x = 5
函式外 x = 10

區域變數會覆蓋同名的全域變數,但不會改變外部的值。

二、在函式內修改全域變數

count = 0  # 全域變數

def increment():
    global count
    count += 1
    print("函式內 count =", count)

increment()
print("函式外 count =", count)

輸出:

函式內 count = 1
函式外 count = 1

使用 global 關鍵字可以讓函式內部修改全域變數的值。

三、嵌套函式與 nonlocal

def outer():
    num = 10
    def inner():
        nonlocal num
        num += 5
        print("inner num =", num)
    inner()
    print("outer num =", num)

outer()

輸出:

inner num = 15
outer num = 15

nonlocal 用於內層函式修改外層函式的變數(非全域)。

錯誤情境

螢幕擷取畫面 2025-08-14 160405
Python 在函式內偵測到有同名變數賦值,就會視為區域變數,即使你想讀取全域的值也會報錯。

解決方法:
讀取前加上 global x更改變數名稱避免衝突
螢幕擷取畫面 2025-08-14 162834

生命週期(Variable Lifetime)與作用域

作用域(Scope) 是「哪裡可以存取這個變數」
生命週期(Lifetime) 是「這個變數存在多久」

def my_func():
    x = 10  # 區域變數
    print(x)

my_func()
print(x)  # 會出錯,因為 x 已經不存在

x 的生命週期:

  • 在 my_func() 被呼叫的那一刻建立
  • 函式執行結束後被釋放(消失)

生命週期的分類

區域變數(Local Variable)

  • 建立時間:進入函式(或區塊)時
  • 消失時間:函式執行結束時
  • 生命週期很短,只存在於函式執行期間

全域變數(Global Variable)

  • 建立時間:程式開始執行時(或第一次被宣告時)
  • 消失時間:程式結束時
  • 生命週期較長,通常貫穿整個程式

學習心得

今天的主題讓我更理解變數的「生命週期」與「存取範圍」。
我覺得「生命週期」是一個很有趣的說法:一個變數從建立到消失的整個過程,也就是它在記憶體中存在的時間長短,讓死板板的程式看起來更有生命力了!
關於生命週期,也有一個很形象的比喻——區域變數就像是餐廳臨時借你的桌子,只在你用餐期間存在;全域變數則像是餐廳的收銀台,從開店到打烊都在那裡。
以前在 Java 時,我對作用域的印象比較單純,因為變數幾乎都在方法或類別內定義,很少會混淆。但 Python 有時候容易讓我誤以為在修改全域變數,實際上卻只是建立了一個新的區域變數。
global 和 nonlocal 雖然能解決作用域問題,但使用過多會讓程式變得不易維護,所以在能用傳參數或回傳值解決的情況下,還是要盡量避免直接改全域變數。
明天我要學習模組(import) 與 math / random,開始嘗試使用 Python 內建工具庫,讓程式功能更強大、更方便!


上一篇
Day 11 - 自訂函式與參數、return
下一篇
Day 13 – 模組(import)與 math / random
系列文
從零開始學 Python30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言